home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
bd3.zip
/
BD3.ADA
next >
Wrap
Text File
|
1989-03-13
|
20KB
|
541 lines
package BANK is
--------------------------------------------------------------------------
--| BEGIN PROLOGUE
--| DESCRIPTION : BANK defines a bank, the TELLER objects
--| : within it, and the procedure PRINT_REPORT
--| : (which reports on the status of the BANK).
--| :
--| : BANK is an abstract state machine, defining
--| : a BANK object which contains TELLER objects.
--| :
--| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
--| : object-oriented design and tasking
--| : with Ada
--| :
--| LIMITATIONS : None
--| AUTHOR(S) : Richard Conn (RLC)
--| CHANGE LOG : 1/16/89 RLC Initial Design and Code
--| CHANGE LOG : 2/25/89 RLC Final Review Prior to Release
--| REMARKS : None
--| PORTABILITY ISSUES : None
--| END PROLOGUE
--------------------------------------------------------------------------
-- TRANSACTION requested of a TELLER
type TRANSACTION is (ADD_NEW_CUSTOMER,
GET_BALANCE,
MAKE_DEPOSIT,
MAKE_WITHDRAWAL);
-- Unit of currency
type DOLLAR is new FLOAT;
-- Identification of a CUSTOMER
type CUSTOMER_ID is new NATURAL range 1 .. NATURAL'LAST;
-- Index of and Number of TELLER objects within the bank
type TELLER_INDEX is new NATURAL range 1 .. 4;
-- A TELLER_PERSON is an object to which a CUSTOMER may make a REQUEST
-- The BANK tells the TELLER_PERSON to START_WORK, giving the
-- TELLER_PERSON its TELLER_NUMBER
task type TELLER_PERSON is
entry REQUEST(ID : in out CUSTOMER_ID;
KIND : in TRANSACTION;
AMOUNT : in out DOLLAR);
end TELLER_PERSON;
-- These are the TELLER objects available at the bank
TELLER : array(TELLER_INDEX) of TELLER_PERSON;
-- PRINT_REPORT gives the transaction log of all the bank
-- customers
procedure PRINT_REPORT;
-- STOP_WORK terminates all TELLER tasks
procedure STOP_WORK;
end BANK;
--
with CONSOLE;
package body BANK is
--------------------------------------------------------------------------
--| BEGIN PROLOGUE
--| DESCRIPTION : Package Body BANK implements the TELLER
--| : tasks and the PRINT_REPORT procedure.
--| : CUSTOMER data is maintained within the
--| : BANK as a linked list.
--| :
--| REQUIREMENTS SUPPORTED : Bank Demonstration Program to show
--| : object-oriented design and tasking
--| : with Ada
--| :
--| LIMITATIONS : None
--| AUTHOR(S) : Richard Conn (RLC)
--| CHANGE LOG : 1/16/89 RLC Initial Design and Code
--| CHANGE LOG : 2/25/89 RLC Final Review Prior to Release
--| REMARKS : None
--| PORTABILITY ISSUES : Uses CONSOLE (TEXT_IO), so is very portable;
--| : no known portability problems.
--| END PROLOGUE
--------------------------------------------------------------------------
-- Identifier of next customer
NEXT_ID : CUSTOMER_ID := CUSTOMER_ID'FIRST;
-- Linked list of customer data
type CUSTOMER_DATA;
type CUSTOMER_DATA_POINTER is access CUSTOMER_DATA;
type CUSTOMER_DATA is record
ID : CUSTOMER_ID;
BALANCE : DOLLAR := 0.0;
TRANSACTION_COUNT : NATURAL := 0;
ATTEMPTED_OVERDRAWS : NATURAL := 0;
NEXT : CUSTOMER_DATA_POINTER := null;
end record;
-- Count of number of transactions for each TELLER object
TELLER_TRANSACTION_COUNT : array(TELLER_INDEX) of NATURAL
:= (others => 0);
-- Pointers to first and last customer data entries
FIRST_CUSTOMER : CUSTOMER_DATA_POINTER := null;
LAST_CUSTOMER : CUSTOMER_DATA_POINTER := null;
--
-- package body BANK
-- Print a report of the status of the BANK
procedure PRINT_REPORT is
CURRENT_CUSTOMER : CUSTOMER_DATA_POINTER;
begin
-- Check for any customers and issue an error message if none
if NEXT_ID = CUSTOMER_ID'FIRST then
CONSOLE.WRITE("The bank doesn't have any customers");
CONSOLE.WRITE(CONSOLE.NEW_LINE);
-- Generate report
else
-- Customer balance, transaction count, attempted overdraw
-- count report
CONSOLE.WRITE("**** BANK STATUS REPORT ****");
CONSOLE.WRITE(CONSOLE.NEW_LINE);
CONSOLE.WRITE(
"Customer Balance Transactions Attempted_Overdraws");
CONSOLE.WRITE(CONSOLE.NEW_LINE);
CURRENT_CUSTOMER := FIRST_CUSTOMER;
while CURRENT_CUSTOMER /= null loop
CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.ID), 5);
CONSOLE.WRITE(" ");
CONSOLE.WRITE(FLOAT(CURRENT_CUSTOMER.BALANCE), 8, 2);
CONSOLE.WRITE(" ");
CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.TRANSACTION_COUNT), 8);
CONSOLE.WRITE(" ");
CONSOLE.WRITE(INTEGER(CURRENT_CUSTOMER.ATTEMPTED_OVERDRAWS),
8);
CONSOLE.WRITE(CONSOLE.NEW_LINE);
CURRENT_CUSTOMER := CURRENT_CUSTOMER.NEXT;
end loop;
CONSOLE.WRITE(CONSOLE.NEW_LINE);
-- Teller transaction count report
CONSOLE.WRITE("Teller : ");
for I in TELLER_INDEX loop
CONSOLE.WRITE(INTEGER(I), 8);
end loop;
CONSOLE.WRITE(CONSOLE.NEW_LINE);
CONSOLE.WRITE("Transaction_Count: ");
for I in TELLER_INDEX loop
CONSOLE.WRITE(INTEGER(TELLER_TRANSACTION_COUNT(I)), 8);
end loop;
CONSOLE.WRITE(CONSOLE.NEW_LINE);
end if;
end PRINT_REPORT;
-- Terminate all TELLER tasks
procedure STOP_WORK is
begin
for I in TELLER_INDEX loop
abort TELLER(I);
end loop;
end STOP_WORK;
--
-- package body BANK
-- FIND_CUSTOMER is used to find a CUSTOMER_DATA record
-- based on a CUSTOMER_ID number
function FIND_CUSTOMER(ID : in CUSTOMER_ID)
return CUSTOMER_DATA_POINTER is
CURRENT_CUSTOMER : CUSTOMER_DATA_POINTER;
begin
CURRENT_CUSTOMER := FIRST_CUSTOMER;
while CURRENT_CUSTOMER /= null loop
exit when CURRENT_CUSTOMER.ID = ID;
CURRENT_CUSTOMER := CURRENT_CUSTOMER.NEXT;
end loop;
return CURRENT_CUSTOMER;
end FIND_CUSTOMER;
--
-- package body BANK
task TELLER_ASSIGNER is
-- This task assigns an ID number to a teller.
-- TELLER_ASSIGNER is called by the TELLER_PERSON task when the
-- TELLER_PERSON task first starts up.
entry GET_TELLER_ID(ID : out TELLER_INDEX);
end TELLER_ASSIGNER;
task body TELLER_ASSIGNER is
NEXT_TELLER_ID : TELLER_INDEX := TELLER_INDEX'FIRST;
begin
loop
accept GET_TELLER_ID(ID : out TELLER_INDEX) do
ID := NEXT_TELLER_ID;
if NEXT_TELLER_ID /= TELLER_INDEX'LAST then
NEXT_TELLER_ID := NEXT_TELLER_ID + 1;
end if;
end GET_TELLER_ID;
end loop;
end TELLER_ASSIGNER;
--
-- package body BANK
-- Implementation of a TELLER task
task body TELLER_PERSON is
THIS_CUSTOMER : CUSTOMER_DATA_POINTER;
MY_NUMBER : TELLER_INDEX;
begin
-- TELLER gets his ID number
TELLER_ASSIGNER.GET_TELLER_ID(MY_NUMBER);
-- TELLER loops on REQUESTs from CUSTOMERs
loop
accept REQUEST(ID : in out CUSTOMER_ID;
KIND : in TRANSACTION;
AMOUNT : in out DOLLAR) do
-- Increment teller's transaction count
TELLER_TRANSACTION_COUNT(MY_